﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace GMusicUtil.Common.Commands
{
    public class DelegateCommand<T> : ICommand
    {
        public event EventHandler CanExecuteChanged = null;

        public DelegateCommand(Action<T> execute)
            : this(execute, null)
        {
        }

        public DelegateCommand(Action<T> execute, Predicate<T> canExecute)
        {
            ExecuteAction = execute;
            CanExecuteAction = canExecute;
        }

        private Predicate<T> CanExecuteAction { get; set; }
        private Action<T> ExecuteAction { get; set; }

        public virtual bool CanExecute(object parameter)
        {
            return (CanExecuteAction == null) ? true : CanExecuteAction((T)parameter);
        }

        public virtual void Execute(object parameter)
        {
            ExecuteAction((T)parameter);
        }

        public void RaiseCanExecuteChanged()
        {
            RaiseCanExecuteChanged(CanExecuteChanged);
        }

        protected virtual void RaiseCanExecuteChanged(EventHandler canExecuteChanged)
        {
            if (canExecuteChanged != null)
            {
                canExecuteChanged(this, EventArgs.Empty);
            }
        }
    }

    public class DelegateCommand : DelegateCommand<object>
    {
        public DelegateCommand(Action execute)
            : base(_ => execute(), null)
        {
        }

        public DelegateCommand(Action execute, Func<bool> canExecute)
            : base(_ => execute(), _ => canExecute())
        {
        }
    }

    public static partial class ExtensionMethods
    {
        public static bool CanExecute(this ICommand command)
        {
            return command.CanExecute(null);
        }

        public static void Execute(this ICommand command)
        {
            command.Execute(null);
        }
    }
}
